home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr11 / ddj9304.zip / DIFFCOMP.ZIP / PACK.C < prev    next >
Text File  |  1992-11-24  |  4KB  |  133 lines

  1. /****************************************************************************/
  2. /*                                 PACK.C                                   */
  3. /* By James Sylvester -- From DDJ for February 1993 -- Last Updated 9/22/92 */
  4. /****************************************************************************/
  5.  
  6. #include <stdio.h>
  7.  
  8. void main(int argc, char *argv[])
  9. {
  10.   const blockfactor = 1;              /* adjust as desired */
  11.   const blocksize = blockfactor * 8;
  12.   char  buffer [257] [8];             /* enter blocksize for second index */
  13.  
  14.   int   i, j, currentsize;
  15.   FILE  *sf, *tf;               /* sourcefile & targetfile respectively */
  16.   int   bestblock;              /* best matching block in buffer */
  17.   int   bestcount, matchcount;
  18.   int   changeindex, bitvalue;
  19.  
  20.  
  21. /* Verify and perform error handling for opening both the input file and   */
  22. /* the output file as binary files.  Note, the input file has the original */
  23. /* data and the output file will contain the encoded/compressed data.      */
  24.  
  25.   if (argc != 3)
  26.   {
  27.     printf("Correct usage is  >pack source_filename target_filename\n");
  28.     exit(1);
  29.   }
  30.   if ((sf = fopen(argv[1], "rb"))==NULL)  /* read only mode for input file */
  31.   {
  32.     printf("Unable to open source file %s\n", argv[1]);
  33.     exit(2);
  34.   }
  35.   if ((tf = fopen(argv[2], "wb"))==NULL)  /* write only mode for output file */
  36.   {
  37.     printf("Unable to open target file %s\n", argv[2]);
  38.     exit(3);
  39.   }
  40.  
  41.  
  42. /* Initialize buffer with all zeros in the first block, all ones in the   */
  43. /* second block, and so forth so that there will be at least one matching */
  44. /* byte in the first block of input data regardless what it might be.     */
  45.  
  46.   for (i = 0; i < 256; i++)
  47.     for (j = 0; j < blocksize; j++)
  48.       buffer [i] [j] = i;
  49.  
  50.  
  51.   while (1)  /* while true ==> stay in loop until internal exit */
  52.   {
  53.  
  54.  
  55. /* Load the next block of data from the sourcefile into the last slot of */
  56. /* the buffer.  Also, keep track of how many bytes were read to signify  */
  57. /* proper handling for the unfull block when at the end of file.         */
  58.  
  59.     currentsize = blocksize;
  60.     for (j = 0; j < blocksize; j++)
  61.     {
  62.       i = getc(sf);
  63.       if (i == EOF)
  64.       {
  65.         currentsize = j;     /* reset correct currentsize */
  66.         break;               /* exit for loop */
  67.       }
  68.       buffer [256] [j] = i;  /* put character into last block */
  69.     }
  70.  
  71.     if (currentsize == 0)    /* input data ended with previous full block */
  72.     {
  73.       printf("%s now contains encoded/compressed data!\n", argv[2]);
  74.       exit(4);
  75.     }
  76.  
  77.  
  78. /* Find the best matching block in buffer for the recently loaded block */
  79. /* of input data.  Afterwards, send the bestblock index to the output   */
  80. /* file and process the changes between the two blocks.                 */
  81.  
  82.     bestcount = -1;
  83.     for (i = 0; i < 256; i++)
  84.     {
  85.       matchcount = 0;
  86.       for (j = 0; j < currentsize; j++)
  87.         if (buffer [i] [j] == buffer [256] [j])
  88.           matchcount++;
  89.       if (matchcount > bestcount)
  90.       {
  91.         bestcount = matchcount;
  92.         bestblock = i;
  93.         if (bestcount == currentsize)
  94.           break;                       /* exit for loop */
  95.       }
  96.     }
  97.     putc (bestblock, tf);
  98.     for (i = 0; i < blockfactor; i++)
  99.     {
  100.       changeindex = 0;
  101.       bitvalue = 1;
  102.       for (j = i*8; j < i*8+8; j++)
  103.       {
  104.         if (j >= currentsize)
  105.           break;
  106.         if (buffer [bestblock] [j] != buffer [256] [j])
  107.           changeindex += bitvalue;
  108.         bitvalue *= 2;
  109.       }
  110.       putc(changeindex, tf);
  111.       for (j = i*8; j < i*8+8; j++)
  112.       {
  113.         if (changeindex % 2 == 1)
  114.           putc(buffer [256] [j], tf);
  115.         changeindex /= 2;
  116.       }
  117.     }
  118.  
  119.     if (currentsize < blocksize)  /* input data ended with unfull block */
  120.     {
  121.       putc(currentsize, tf);
  122.       printf("%s now contains encoded/compressed data!\n", argv[2]);
  123.       exit(5);
  124.     }
  125.  
  126.     /* Update the best matching block in buffer with new data. */
  127.     /* Compression should now improve as further loaded blocks */
  128.     /* closely match the exact copies kept in the buffer.      */
  129.  
  130.     for (j = 0; j < blocksize; j++)
  131.       buffer [bestblock] [j] = buffer [256] [j];
  132.   }
  133. }